﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using znq;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public int startRow;
        public int timeCol;
        public int sCol;
        public int fCol;
        public int leftBar;
        public int rightBar;
        public double sRatio;
        public double fRatio;
        public int dePeriod;

        public double axis_x_min, axis_x_max;
        public int axis_y_min, axis_y_max;

        public int k1_threshold = 1, k2_threshold = 1;

        private List<double> arr0 = new List<double>();
        private List<double> arr1 = new List<double>();
        private List<double> arr2 = new List<double>();

        private List<int> topArr = new List<int>();
        private List<int> bottomArr = new List<int>();
        private List<int> zeroArr = new List<int>();

        private string currentFile;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            setAttribute();
            znq.Control control = new znq.Control(this);
            control.ShowDialog();
        }

        #region 入口函数：起到刷新作用

        //获取所选择的文件并进行绘图
        public void freshChart()
        {
            if (comboBox2.SelectedValue != null)
            {
                string filePath = comboBox2.SelectedValue.ToString();
                if (File.Exists(filePath))
                {
                    render(filePath);
                }
            }
        }

        //主函数：渲染图形 0代表全部图形
        public void render(string filePath)
        {
            int period = 0;
            resetAttribute();
            readFromFile(filePath);
            getKeyPoint();
            if (dataIsAvailable())
            {
                int pCount = this.getPeriodNum();
                if (period == 0)
                {
                    period = getDefaultPeriod();
                }
                setLableText(period);

                for (int i = 0; i <= pCount; i++)
                {
                    comboBox1.Items.Add(i);
                }

                comboBox1.SelectedIndex = 0;
            }
            else
            {
                MessageBox.Show("文件数据存在问题");
            }

        }

        #endregion

        #region 读取文件中的内容

        //判断文件类型已决定是用什么方式打开
        public void readFromFile(string filePath)
        {
            string extension = Path.GetExtension(filePath);
            string lowerExt = extension.ToLower();
            if (lowerExt == ".txt")
            {
                readFromText(filePath);
            }
            else if (lowerExt == ".xls" || lowerExt == ".xlsx")
            {
                readFromExcelByOleDB(filePath);

                if (arr0.Count == 0 && arr1.Count == 0 && arr2.Count == 0)
                {
                    readFromText(filePath);
                }
                if (arr0.Count == 0 && arr1.Count == 0 && arr2.Count == 0)
                {
                    saveAsNewExcel(filePath);
                }
                if (arr0.Count == 0 && arr1.Count == 0 && arr2.Count == 0)
                {
                    readFromExcelByCom(filePath);
                }
            }
            if(arr0.Count() != arr1.Count() || arr0.Count() != arr2.Count() || arr1.Count() != arr2.Count())
            {
                int num = arr0.Count();
                if (num > arr1.Count())
                {
                    num = arr1.Count();
                }
                if (num > arr2.Count())
                {
                    num = arr2.Count();
                }

                if (arr0.Count() != num)
                {
                    arr0.RemoveRange(num - 1, arr0.Count() - num);
                }
                if (arr1.Count() != num)
                {
                    arr1.RemoveRange(num - 1, arr1.Count() - num);
                }
                if (arr2.Count() != num)
                {
                    arr2.RemoveRange(num - 1, arr2.Count() - num);
                }
            }
            

        }

        //从text文件中读取数据
        public void readFromText(string filePath)
        {
            string fileName = Path.GetFileName(filePath);
            try
            {
                StreamReader rd = File.OpenText(filePath);
                for (int i = 0; i < startRow; i++)
                {
                    rd.ReadLine();
                }

                string s;
                int j = 0;
                while ((s = rd.ReadLine()) != null)
                {
                    string[] rowArr = s.Split(new string[] { "\t", " ", ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
                    if (timeCol == 0)
                    {
                        arr0.Add((double)j);
                    }
                    else
                    {
                        arr0.Add(double.Parse(rowArr[timeCol - 1].ToString()));
                    }
                    arr1.Add(double.Parse(rowArr[sCol - 1].ToString()) * sRatio);
                    arr2.Add(double.Parse(rowArr[fCol - 1].ToString()) * fRatio);
                    j++;
                }
                rd.Close();
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "读取成功\r\n");
            }
            catch (Exception ex)
            {
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "读取失败:" + ex.Message + "\r\n");
            }

        }

        //从Excel中读取数据
        public void readFromExcelByCom(string filePath)
        {
            string fileName = Path.GetFileName(filePath);
            object missing = System.Reflection.Missing.Value;
            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Visible = false;
            excel.UserControl = true;
            if (excel == null)
            {
                MessageBox.Show("创建Excel对象失败");
            }
            else
            {
                Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Open(filePath, missing, true, missing, missing, missing, missing, missing, missing, true, missing, missing, missing, missing, missing);
                Microsoft.Office.Interop.Excel.Worksheet worksheet = workbook.Worksheets.get_Item(1);
                Microsoft.Office.Interop.Excel.Range range = worksheet.UsedRange;
                int rows = range.Cells.Rows.Count;
                int cols = range.Cells.Columns.Count;

                object[,] arryItem = (object[,])range.Value2;   //get range's value
                for (int i = startRow; i <= rows; i++)
                {
                    if (timeCol == 0)
                    {
                        arr0.Add((double)i);
                    }
                    else
                    {
                        arr0.Add(double.Parse(arryItem[i, timeCol].ToString()));
                    }
                    arr1.Add(double.Parse(arryItem[i, sCol].ToString()) * sRatio);
                    arr2.Add(double.Parse(arryItem[i, fCol].ToString()) * fRatio);
                }

                workbook.Close();
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "读取成功\r\n");

            }

            excel.Quit();
            excel = null;
        }

        //利用oledb来读取excel
        public void readFromExcelByOleDB(string filePath)
        {
            string fileName = Path.GetFileName(filePath);
            string connStr = "";

            string fileType = Path.GetExtension(filePath);
            if (fileType == ".xls")
                connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filePath + ";" + ";Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1\"";
            else
                connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + filePath + ";" + ";Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1\"";
            string sql_F = "Select * FROM [{0}]";
            OleDbConnection conn = null;
            OleDbDataAdapter da = null;
            DataTable dataTable = new DataTable();
            try
            {
                // 初始化连接，并打开                  
                conn = new OleDbConnection(connStr);
                conn.Open();
                DataTable schemaTable = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
                string tableName = schemaTable.Rows[0][2].ToString().Trim();
                da = new OleDbDataAdapter();
                da.SelectCommand = new OleDbCommand(String.Format(sql_F, tableName), conn);
                da.Fill(dataTable);
            }
            catch (Exception ex)
            {
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  读取文件出现错误：" + ex.Message + "\r\n");
            }
            finally
            {
                // 关闭连接                  
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                    da.Dispose();
                    conn.Dispose();
                }
            }

            int rows = dataTable.Rows.Count;
            int cols = dataTable.Columns.Count;

            if (rows >= startRow)
            {
                for (int i = startRow - 1; i < rows; i++)
                {
                    if (timeCol == 0)
                    {
                        arr0.Add((double)i);
                    }
                    else
                    {
                        arr0.Add(double.Parse(dataTable.Rows[i][timeCol - 1].ToString()));
                    }
                    arr1.Add(double.Parse(dataTable.Rows[i][sCol - 1].ToString()) * sRatio);
                    arr2.Add(double.Parse(dataTable.Rows[i][fCol - 1].ToString()) * fRatio);
                }

                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "读取成功\r\n");
            }
            else
            {
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "读取失败\r\n");
            }

        }

        //这种情况用于excel不是标准的excel，把它另存为标准的后再进行读取
        public void saveAsNewExcel(string filePath)
        {
            string directory = Path.GetDirectoryName(filePath);
            string fileName = Path.GetFileNameWithoutExtension(filePath);
            string extension = Path.GetExtension(filePath);
            string newFile = directory + @"\" + fileName + "_new.xls";
            try
            {
                if (!File.Exists(newFile))
                {
                    object missing = System.Reflection.Missing.Value;
                    Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
                    excel.Visible = false;
                    excel.UserControl = true;
                    excel.DisplayAlerts = false;
                    if (excel == null)
                    {
                        MessageBox.Show("创建Excel对象失败");
                    }
                    else
                    {
                        Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Open(filePath, missing, false, missing, missing, missing, missing, missing, missing, true, missing, missing, missing, missing, missing);
                        workbook.SaveAs(newFile, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal);
                        workbook.Close();
                        workbook = null;
                    }
                    excel.Quit();
                    excel = null;
                    textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "另存成功\r\n");
                }
            }
            catch (Exception ex)
            {
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "另存失败:" + ex.Message + "\r\n");
            }
            readFromExcelByOleDB(newFile);
        }

        //读取所选文件路径，并且更新文件选择下拉框
        public void dealFilePath(string[] files)
        {
            ArrayList fileArr = new ArrayList();
            for (int i = 0; i < files.Count(); i++)
            {
                string filePath = files[i];
                string fileName = Path.GetFileName(filePath);
                fileArr.Add(new Item(@fileName, @filePath));
            }

            comboBox2.DataSource = fileArr;
            comboBox2.DisplayMember = "Text";
            comboBox2.ValueMember = "Value";

            currentFile = files[0];
            comboBox2.SelectedIndexChanged += new EventHandler(comboBox2_SelectedIndexChanged);
            freshChart();
        }

        #endregion

        #region 读取数据之后将得到的数据处理，得到关键点

        //获取零点、最高点、最低点
        public void getKeyPoint()
        {
            int start;
            int end;
            for (int i = 0; i < arr1.Count; i++)
            {
                if (i < leftBar)
                {
                    start = 0;
                    end = i + rightBar;
                }
                else if (arr1.Count - rightBar < i)
                {
                    start = i - leftBar;
                    end = arr1.Count - 2;
                }
                else
                {
                    start = i - leftBar;
                    end = i + rightBar;
                }

                if (isTop(i, start, end) == true)
                {
                    topArr.Add(i);
                }

                if (isBottom(i, start, end) == true)
                {
                    bottomArr.Add(i);
                }
            }
            filterTopAndBottom();
            getZeroArr();
            validateKeyPoint();
            initThreshold();
        }

        //初始化计算k1，k2的阀值
        private void initThreshold()
        {
            k1_threshold = Math.Abs(topArr[0] - bottomArr[0]) / 20;
            k2_threshold = Math.Abs(topArr[0] - bottomArr[0]) / 8;
        }

        //获取零点数组
        private void getZeroArr(bool normal = true)
        {
            int half = Math.Abs(topArr[0] - bottomArr[0]);
            int start;
            int end;

            if (normal == true)
            {
                if (topArr[0] > bottomArr[0])
                {
                    start = bottomArr[0] - half;
                }
                else
                {
                    start = topArr[0] - half;
                }

                if (start - leftBar < 0) start = leftBar;

                if (topArr.Last() > bottomArr.Last())
                {
                    end = topArr.Last() + half;
                }
                else
                {
                    end = bottomArr.Last() + half;
                }

                if ((end + rightBar) > arr1.Count()) end = arr1.Count() - rightBar;

                for (int i = start; i < end; i++)
                {
                    if (isZero(i, i - leftBar, i + rightBar))
                    {
                        zeroArr.Add(i);
                    }
                }
            }
            else
            {
                start = leftBar;
                end = arr1.Count() - rightBar;
                for (int i = 0; i < arr1.Count; i++)
                {
                    if (i < leftBar)
                    {
                        start = 0;
                        end = i + rightBar;
                    }
                    else if (arr1.Count - rightBar < i)
                    {
                        start = i - leftBar;
                        end = arr1.Count - 2;
                    }
                    else
                    {
                        start = i - leftBar;
                        end = i + rightBar;
                    }

                    if (isZero(i, start, end))
                    {
                        zeroArr.Add(i);
                    }
                }
            }

            filterZero();
        }

        //过滤零点
        private void filterZero()
        {
            int half = Math.Abs(topArr[0] - bottomArr[0]);
            for (int i = zeroArr.Count() - 1; i > 0; i--)
            {
                if ((zeroArr[i] - zeroArr[i - 1]) < half / 2)
                {
                    zeroArr.RemoveAt(i - 1);
                }
            }
        }

        //判断是否是零点
        private bool isZero(int index, int start, int end)
        {
            double max = arr1.Max();
            double item = Math.Abs(arr1[index]);
            List<double> absArr = new List<double>();
            for (int i = start; i < end; i++)
            {
                absArr.Add(Math.Abs(arr1[i]));
            }

            if (absArr.Min() == item && item < max / 4)
            {
                return true;
            }
            return false;
        }

        //对最大值点进行过滤
        private void filterTopAndBottom()
        {
            int half = Math.Abs(topArr[0] - bottomArr[0]);
            for (int i = topArr.Count() - 1; i > 0; i--)
            {
                if ((topArr[i] - topArr[i - 1]) < half)
                {
                    topArr.RemoveAt(i - 1);
                }
            }

            for (int i = bottomArr.Count() - 1; i > 0; i--)
            {
                if ((bottomArr[i] - bottomArr[i - 1]) < half)
                {
                    bottomArr.RemoveAt(i - 1);
                }
            }
        }

        //判断是否是最低点
        private bool isBottom(int index, int start, int end)
        {
            double min = arr1.Min();
            double item = arr1[index];
            double minValue = 0.0;
            for (int i = start; i < end; i++)
            {
                if (arr1[i] < minValue)
                {
                    minValue = arr1[i];
                }
            }

            if (minValue == item && item < min / 2)
            {
                return true;
            }
            return false;
        }

        //判断是否是最高点
        public bool isTop(int index, int start, int end)
        {
            double max = arr1.Max();
            double item = arr1[index];
            double maxValue = 0.0;
            for (int i = start; i < end; i++)
            {
                if (arr1[i] > maxValue)
                {
                    maxValue = arr1[i];
                }
            }

            if (maxValue == item && item > max / 2)
            {
                return true;
            }
            return false;
        }

        //验证三列数组
        public void validateKeyPoint()
        {
            if (dataIsAvailable() == false)
            {
                zeroArr.Clear();
                getZeroArr(false);
            }

            if (topArr.Count() == bottomArr.Count() && topArr.Count() < (zeroArr.Count - 1.0) / 2.0)
            {
                int start = topArr[0] > bottomArr[0] ? bottomArr[0] : topArr[0];
                int end = topArr.Max() > bottomArr.Max() ? topArr.Max() : bottomArr.Max();
                int m = -1, n = -1;
                for (int i = 0; i < zeroArr.Count(); i++)
                {
                    if (zeroArr[i] > start)
                    {
                        m = i - 2;
                        break;
                    }
                }
                for (int i = 0; i < zeroArr.Count(); i++)
                {
                    if (zeroArr[i] > end)
                    {
                        n = i + 1;
                        break;
                    }
                }

                if (n > 0 && n <= zeroArr.Count()) zeroArr.RemoveRange(n, zeroArr.Count() - n);
                if (m >= 0) zeroArr.RemoveRange(0, m + 1);

            }

        }

        #endregion

        #region 对数据处理以后，获取需要的结果

        //获取某个周期的结果《从1开始》
        private Dictionary<string, double> getResult(int period)
        {
            Dictionary<string, double> re = new Dictionary<string, double>();
            try
            {
                double zeroS1 = 0.0;
                double zeroF1 = 0.0;
                double zeroS2 = 0.0;
                double zeroF2 = 0.0;
                double maxS = 0.0;
                double maxF = 0.0;
                double minS = 0.0;
                double minF = 0.0;
                double k1_left = 0.0;
                double k1_right = 0.0;
                double k2_top = 0.0;
                double k2_bottom = 0.0;

                zeroS1 = arr1[zeroArr[(period - 1) * 2]];
                zeroF1 = arr2[zeroArr[(period - 1) * 2]];
                zeroS2 = arr1[zeroArr[(period - 1) * 2 + 1]];
                zeroF2 = arr2[zeroArr[(period - 1) * 2 + 1]];
                maxS = arr1[topArr[period - 1]];
                maxF = arr2[topArr[period - 1]];
                minS = arr1[bottomArr[period - 1]];
                minF = arr2[bottomArr[period - 1]];


                re.Add("zero_1_s", zeroS1); re.Add("zero_1_f", zeroF1);
                re.Add("zero_2_s", zeroS2); re.Add("zero_2_f", zeroF2);
                re.Add("top_s", maxS); re.Add("top_f", maxF);
                re.Add("bottom_s", minS); re.Add("bottom_f", minF);

                //获取损耗因子
                double shyz = Math.Abs(zeroF1 / maxF);
                re.Add("shyz", shyz);

                //获取最大值和最小值
                double maxValue = 0.0;
                double minValue = 0.0;
                getMaxAndMinValue(ref maxValue, ref minValue, period);
                re.Add("maxValue", maxValue);
                re.Add("minValue", minValue);

                //计算阻尼比
                double ed = getEd(period);
                double ed2 = getEd2(period);
                double es0 = 0.5 * (0.5 * (maxValue - minValue)) * (0.5 * (maxS - minS));
                double znb = ed / (4 * Math.PI * es0);
                double znb2 = ed2 / (4 * Math.PI * es0);
                re.Add("znb", znb);
                re.Add("znb2", znb2);

                //计算表观剪切模量值
                double jqml = Math.Abs((maxValue - minValue) / (maxS - minS));
                re.Add("jqml", jqml);

                getK1(ref k1_left, ref k1_right, period);
                re.Add("k1_left", k1_left);
                re.Add("k1_right", k1_right);

                getK2(ref k2_top, ref k2_bottom, period);
                re.Add("k2_top", k2_top);
                re.Add("k2_bottom", k2_bottom);

            }
            catch (Exception ex)
            {
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  获取结果错误" + ex.Message + "\r\n");
            }

            return re;

        }

        //获取K1的斜率
        private void getK1(ref double k1_left, ref double k1_right, int period)
        {
            double left_x1, left_y1, left_x2, left_y2, right_x1, right_y1, right_x2, right_y2;
            this.getK1PointsByPeriod(
                period,
                out left_x1,
                out left_y1,
                out left_x2,
                out left_y2,
                out right_x1,
                out right_y1,
                out right_x2,
                out right_y2
            );

            k1_left = (left_y2 - left_y1) / (left_x2 - left_x1);
            k1_right = (right_y2 - right_y1) / (right_x2 - right_x1);
        }

        //根据周期获取K1的四个点的坐标
        private void getK1PointsByPeriod(
            int period,
            out double left_x1,
            out double left_y1,
            out double left_x2,
            out double left_y2,
            out double right_x1,
            out double right_y1,
            out double right_x2,
            out double right_y2
        )
        {
            int left1 = topArr[0] < bottomArr[0] ? bottomArr[period - 1] : topArr[period - 1];
            int left2 = left1 + k1_threshold;
            int right1 = topArr[0] < bottomArr[0] ? topArr[period - 1] : bottomArr[period - 1];
            int right2 = right1 + k1_threshold;

            left_x1 = arr1[left1];
            left_y1 = arr2[left1];
            left_x2 = arr1[left2];
            left_y2 = arr2[left2];
            right_x1 = arr1[right1];
            right_y1 = arr2[right1];
            right_x2 = arr1[right2];
            right_y2 = arr2[right2];
        }

        //扩展K1的两个范围点
        public void filterK1Points(ref double x1, ref double y1, ref double x2, ref double y2)
        {
            double min = arr2.Min();
            double max = arr2.Max();

            double tmp_x1 = (x2 - x1) / (y2 - y1) * (min - y1) + x1;
            //if (tmp_x1 < arr1.Min()) { tmp_x1 = arr1.Min(); }
            //if (tmp_x1 > arr1.Max()) { tmp_x1 = arr1.Max(); }

            double tmp_x2 = (x2 - x1) / (y2 - y1) * (max - y1) + x1;
            //if (tmp_x2 < arr1.Min()) { tmp_x2 = arr1.Min(); }
            //if (tmp_x2 > arr1.Max()) { tmp_x2 = arr1.Max(); }

            x1 = tmp_x1;
            y1 = min;
            x2 = tmp_x2;
            y2 = max;
        }

        //获取K2的斜率
        private void getK2(ref double k2_top, ref double k2_bottom, int period)
        {
            double top_left_x, top_left_y, top_right_x, top_right_y, bottom_left_x, bottom_left_y, bottom_right_x, bottom_right_y;
            this.getK2PointsByPeriod(
                period,
                out top_left_x,
                out top_left_y,
                out top_right_x,
                out top_right_y,
                out bottom_left_x,
                out bottom_left_y,
                out bottom_right_x,
                out bottom_right_y
            );

            k2_top = (top_right_y - top_left_y) / (top_right_x - top_left_x);
            k2_bottom = (bottom_right_y - bottom_left_y) / (bottom_right_x - bottom_left_x);
        }

        //根据周期获取K2的四个点的坐标
        private void getK2PointsByPeriod(
            int period,
            out double top_left_x,
            out double top_left_y,
            out double top_right_x,
            out double top_right_y,
            out double bottom_left_x,
            out double bottom_left_y,
            out double bottom_right_x,
            out double bottom_right_y
        )
        {
            int zero1 = zeroArr[(period - 1) * 2];
            int zero2 = zeroArr[(period - 1) * 2 + 1];
            int zero3 = zeroArr[period * 2];
            int top1, top2;
            if (topArr[period - 1] > zero1 && topArr[period - 1] < zero2)
            {
                top1 = topArr[period - 1];
                top2 = bottomArr[period - 1];
            }
            else
            {
                top1 = bottomArr[period - 1];
                top2 = topArr[period - 1];
            }

            int tmp = Math.Abs(topArr[0] - bottomArr[0]) / 2 - k2_threshold;
            if (tmp < 0) tmp = 0;

            int top_left = (top2 + tmp) > zero3 ? zero3 : (top2 + tmp);
            int top_right = zero1 + k2_threshold;
            int bottom_left = zero2 + k2_threshold;
            int bottom_right = zero2 - k2_threshold;

            top_left_x = arr1[top_left];
            top_left_y = arr2[top_left];
            top_right_x = arr1[top_right];
            top_right_y = arr2[top_right];
            bottom_left_x = arr1[bottom_left];
            bottom_left_y = arr2[bottom_left];
            bottom_right_x = arr1[bottom_right];
            bottom_right_y = arr2[bottom_right];
        }

        //扩展K2的两个范围点
        public void filterK2Points(ref double left_x, ref double left_y, ref double right_x, ref double right_y)
        {
            double min = arr1.Min();
            double max = arr1.Max();

            //double chart_x_max = 1.2*arr1.Max();
            //double chart_y_max = 1.2*arr2.Max();
            double y1 = (right_y - left_y) / (right_x - left_x) * (min - left_x) + left_y;
            //if (y1 < -chart_x_max || y1 > chart_x_max)
            //{
            //    if (y1 < -chart_x_max) y1 = -chart_x_max;
            //    if (y1 > chart_x_max) y1 = chart_x_max;
            //    min = (right_x - left_x) / (right_y - left_y) * (y1 - left_y) + left_x;
            //}

            double y2 = (right_y - left_y) / (right_x - left_x) * (max - left_x) + left_y;
            //if (y2 < -chart_y_max || y2 > chart_y_max)
            //{
            //    if (y2 < -chart_y_max) y2 = -chart_y_max;
            //    if (y2 > chart_y_max) y2 = chart_y_max;
            //    max = (right_x - left_x) / (right_y - left_y) * (y2 - left_y) + left_x;
            //}

            left_x = min;
            left_y = y1;
            right_x = max;
            right_y = y2;
        }

        //获取最大值和最小值
        public void getMaxAndMinValue(ref double max, ref double min, int period)
        {
            int start = zeroArr[(period - 1) * 2];
            int end = zeroArr[period * 2];
            for (int i = start; i <= end; i++)
            {
                if (arr2[i] > max) max = arr2[i];
                if (arr2[i] < min) min = arr2[i];
            }
        }

        //获取某个周期的损耗能(传统的方法)
        private double getEd(int period)
        {
            int start = zeroArr[(period - 1) * 2];
            int end = zeroArr[period * 2];
            double ed = 0.0;
            for (int i = start; i <= end; i++)
            {
                double symbol = arr2[i] * arr2[i + 1];
                if (symbol > 0)
                {
                    ed = ed + 0.5 * (arr1[i + 1] - arr1[i]) * (arr2[i + 1] + arr2[i]);
                }
            }
            return ed;
        }

        //获取某个周期的损耗能(设置标准线的方法)
        private double getEd2(int period)
        {
            int start = zeroArr[(period - 1) * 2];
            int end = zeroArr[period * 2];
            double maxS = arr1[topArr[period - 1]];
            double maxF = arr2[topArr[period - 1]];
            double minS = arr1[bottomArr[period - 1]];
            double minF = arr2[bottomArr[period - 1]];
            double ed = 0.0;
            //积分参考线
            double standard = minF < maxF ? minF : maxF;
            //斜率K
            double k = (maxF - minF) / (maxS - minS);
            for (int i = start; i <= end; i++)
            {
                double symbol = arr2[i] * arr2[i + 1];
                if (symbol > 0)
                {
                    double y = k * (arr1[i] - minS) + minF;
                    if (arr2[i] > y)
                        ed = ed + Math.Abs(0.5 * (arr1[i + 1] - arr1[i]) * ((arr2[i + 1] - standard) + (arr2[i] - standard)));
                    if (arr2[i] < y)
                        ed = ed - Math.Abs(0.5 * (arr1[i + 1] - arr1[i]) * ((arr2[i + 1] - standard) + (arr2[i] - standard)));
                }
            }
            return ed;
        }

        #endregion

        #region 将结果写入文件

        //将结果写进文本文件
        public void putDataToText(string[] files)
        {
            for (int i = 0; i < files.Count(); i++)
            {
                string filePath = @files[i];
                string fileName = @Path.GetFileNameWithoutExtension(filePath);
                string fileTrueName = @Path.GetFileName(filePath);
                string dir = @Path.GetDirectoryName(filePath);
                string target = dir + @"\result\" + fileName;
                if (!Directory.Exists(target))
                {
                    Directory.CreateDirectory(target);
                }

                resetAttribute();
                readFromFile(filePath);
                getKeyPoint();
                if (dataIsAvailable())
                {
                    string targetFile = target + @"\result.txt";
                    if (File.Exists(targetFile))
                    {
                        File.Delete(targetFile);
                    }
                    FileStream fs = new FileStream(targetFile, FileMode.Create, FileAccess.Write);
                    StreamWriter sw = new StreamWriter(fs);
                    sw.WriteLine("位置    位移    对应力   最大阻尼力    最小阻尼力    损耗因子    阻尼比    剪切模量");
                    sw.WriteLine();
                    int pCount = this.getPeriodNum();
                    for (int j = 1; j <= pCount; j++)
                    {
                        Dictionary<string, double> result = getResult(j);
                        sw.WriteLine("第一零点    " + result["zero_1_s"].ToString() + "    " + result["zero_1_f"].ToString() + "    " + result["maxValue"].ToString() + "    " + result["minValue"].ToString() + "    " + result["shyz"].ToString("0.00") + "    " + result["znb"].ToString("0.00") + "    " + result["jqml"].ToString("0.00"));
                        sw.WriteLine("最高点    " + result["top_s"].ToString() + "    " + result["top_f"].ToString());
                        sw.WriteLine("第二零点    " + result["zero_2_s"].ToString() + "    " + result["zero_2_f"].ToString());
                        sw.WriteLine("最低点    " + result["bottom_s"].ToString() + "    " + result["bottom_f"].ToString());
                        sw.WriteLine();
                    }
                    textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileTrueName + "结果写入成功\r\n");
                    sw.Close();
                    fs.Close();
                }
                else
                {
                    textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileTrueName + "结果有误，写入失败\r\n");
                }

                lineChart(0, target + @"\image.png");
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileTrueName + "图形保存成功\r\n");

            }

        }

        //将结果写进excel
        public void putDataToExcel(string[] files)
        {
            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            object missing = System.Reflection.Missing.Value;
            excel.Visible = false;
            excel.UserControl = true;
            Microsoft.Office.Interop.Excel.Workbook totalWorkbook = excel.Workbooks.Add();
            Microsoft.Office.Interop.Excel.Sheets oSheets = totalWorkbook.Worksheets;
            oSheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            Microsoft.Office.Interop.Excel.Worksheet simpleTotalWorksheet = totalWorkbook.Worksheets[1];
            simpleTotalWorksheet.Cells[1, 1] = "规格编号";
            simpleTotalWorksheet.Cells[1, 2] = "位移幅值";
            simpleTotalWorksheet.Cells[1, 3] = "力幅值";
            simpleTotalWorksheet.Cells[1, 4] = "等效刚度";
            simpleTotalWorksheet.Cells[1, 5] = "等效阻尼比";
            simpleTotalWorksheet.Cells[1, 6] = "屈后刚度";
            simpleTotalWorksheet.Cells[1, 7] = "屈服力";
            simpleTotalWorksheet.Cells[1, 8] = "屈前刚度";
            simpleTotalWorksheet.Cells[1, 9] = "损耗因子";

            Microsoft.Office.Interop.Excel.Worksheet totalWorksheet = totalWorkbook.Worksheets[2];
            totalWorksheet.Cells[1, 1] = "文件名称";
            totalWorksheet.Cells[1, 2] = "位置";
            totalWorksheet.Cells[1, 3] = "位移";
            totalWorksheet.Cells[1, 4] = "对应力";
            totalWorksheet.Cells[1, 5] = "最大阻尼力";
            totalWorksheet.Cells[1, 6] = "最小阻尼力";
            totalWorksheet.Cells[1, 7] = "损耗因子";
            totalWorksheet.Cells[1, 8] = "阻尼比";
            totalWorksheet.Cells[1, 9] = "剪切模量";
            totalWorksheet.Cells[1, 10] = "K1(左)";
            totalWorksheet.Cells[1, 11] = "K1(右)";
            totalWorksheet.Cells[1, 12] = "K2(上)";
            totalWorksheet.Cells[1, 13] = "K2(下)";

            string totalTarget = Path.GetDirectoryName(files[0]) + @"\结果\综合结果";
            string totalExcelTarget = totalTarget + @"\选定周期综合结果.xls";
            if (!Directory.Exists(totalTarget))
            {
                Directory.CreateDirectory(totalTarget);
            }
            if (File.Exists(totalExcelTarget))
            {
                File.Delete(totalExcelTarget);
            }

            for (int i = 0; i < files.Count(); i++)
            {
                string filePath = @files[i];
                string fileName = @Path.GetFileNameWithoutExtension(filePath);
                //string fileTrueName = Path.GetFileName(filePath);
                string dir = @Path.GetDirectoryName(filePath);
                string loneTarget = dir + @"\结果\单独结果\" + @fileName;

                string loneExcelTarget = loneTarget + @"\" + @fileName + ".xls";
                string loneImageTarget = loneTarget + @"\" + @fileName + ".png";

                string totalImageTarget = totalTarget + @"\" + @fileName + ".png";
                if (!Directory.Exists(loneTarget))
                {
                    Directory.CreateDirectory(loneTarget);
                }

                if (File.Exists(loneExcelTarget))
                {
                    File.Delete(loneExcelTarget);
                }

                resetAttribute();
                readFromFile(filePath);
                getKeyPoint();

                if (dataIsAvailable())
                {
                    int defaultPeriod = getDefaultPeriod();
                    Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Add();
                    Microsoft.Office.Interop.Excel.Worksheet worksheet = workbook.Worksheets[1];
                    worksheet.Cells[1, 1] = "位置";
                    worksheet.Cells[1, 2] = "位移";
                    worksheet.Cells[1, 3] = "对应力";
                    worksheet.Cells[1, 4] = "最大阻尼力";
                    worksheet.Cells[1, 5] = "最小阻尼力";
                    worksheet.Cells[1, 6] = "损耗因子";
                    worksheet.Cells[1, 7] = "阻尼比";
                    worksheet.Cells[1, 8] = "剪切模量";
                    worksheet.Cells[1, 9] = "K1(左)";
                    worksheet.Cells[1, 10] = "K1(右)";
                    worksheet.Cells[1, 11] = "K2(上)";
                    worksheet.Cells[1, 12] = "K2(下)";

                    int pCount = this.getPeriodNum();
                    for (int j = 1; j <= pCount; j++)
                    {
                        Dictionary<string, double> result = getResult(j);
                        worksheet.Cells[(j - 1) * 5 + 2, 1] = "第一零点";
                        worksheet.Cells[(j - 1) * 5 + 2, 2] = result["zero_1_s"];
                        worksheet.Cells[(j - 1) * 5 + 2, 3] = result["zero_1_f"];
                        worksheet.Cells[(j - 1) * 5 + 2, 4] = result["maxValue"];
                        worksheet.Cells[(j - 1) * 5 + 2, 5] = result["minValue"];
                        worksheet.Cells[(j - 1) * 5 + 2, 6] = result["shyz"];
                        worksheet.Cells[(j - 1) * 5 + 2, 7] = result["znb"];
                        worksheet.Cells[(j - 1) * 5 + 2, 8] = result["jqml"];
                        worksheet.Cells[(j - 1) * 5 + 2, 9] = result["k1_left"];
                        worksheet.Cells[(j - 1) * 5 + 2, 10] = result["k1_right"];
                        worksheet.Cells[(j - 1) * 5 + 2, 11] = result["k2_top"];
                        worksheet.Cells[(j - 1) * 5 + 2, 12] = result["k2_bottom"];
                        worksheet.Cells[(j - 1) * 5 + 3, 1] = "最高点";
                        worksheet.Cells[(j - 1) * 5 + 3, 2] = result["top_s"];
                        worksheet.Cells[(j - 1) * 5 + 3, 3] = result["top_f"];
                        worksheet.Cells[(j - 1) * 5 + 4, 1] = "第二零点";
                        worksheet.Cells[(j - 1) * 5 + 4, 2] = result["zero_2_s"];
                        worksheet.Cells[(j - 1) * 5 + 4, 3] = result["zero_2_f"];
                        worksheet.Cells[(j - 1) * 5 + 5, 1] = "最低点";
                        worksheet.Cells[(j - 1) * 5 + 5, 2] = result["bottom_s"];
                        worksheet.Cells[(j - 1) * 5 + 5, 3] = result["bottom_f"];

                        if (j == defaultPeriod)
                        {
                            totalWorksheet.Cells[i * 5 + 2, 1] = fileName;
                            totalWorksheet.Cells[i * 5 + 2, 2] = "第一零点";
                            totalWorksheet.Cells[i * 5 + 2, 3] = result["zero_1_s"];
                            totalWorksheet.Cells[i * 5 + 2, 4] = result["zero_1_f"];
                            totalWorksheet.Cells[i * 5 + 2, 5] = result["maxValue"];
                            totalWorksheet.Cells[i * 5 + 2, 6] = result["minValue"];
                            totalWorksheet.Cells[i * 5 + 2, 7] = result["shyz"];
                            totalWorksheet.Cells[i * 5 + 2, 8] = result["znb"];
                            totalWorksheet.Cells[i * 5 + 2, 9] = result["jqml"];
                            totalWorksheet.Cells[i * 5 + 2, 10] = result["k1_left"];
                            totalWorksheet.Cells[i * 5 + 2, 11] = result["k1_right"];
                            totalWorksheet.Cells[i * 5 + 2, 12] = result["k2_top"];
                            totalWorksheet.Cells[i * 5 + 2, 13] = result["k2_bottom"];
                            totalWorksheet.Cells[i * 5 + 3, 2] = "最高点";
                            totalWorksheet.Cells[i * 5 + 3, 3] = result["top_s"];
                            totalWorksheet.Cells[i * 5 + 3, 4] = result["top_f"];
                            totalWorksheet.Cells[i * 5 + 4, 2] = "第二零点";
                            totalWorksheet.Cells[i * 5 + 4, 3] = result["zero_2_s"];
                            totalWorksheet.Cells[i * 5 + 4, 4] = result["zero_2_f"];
                            totalWorksheet.Cells[i * 5 + 5, 2] = "最低点";
                            totalWorksheet.Cells[i * 5 + 5, 3] = result["bottom_s"];
                            totalWorksheet.Cells[i * 5 + 5, 4] = result["bottom_f"];


                            simpleTotalWorksheet.Cells[i + 2, 1] = fileName;
                            simpleTotalWorksheet.Cells[i + 2, 2] = (Math.Abs(result["top_s"]) / 2 + Math.Abs(result["bottom_s"]) / 2).ToString("0.0");
                            simpleTotalWorksheet.Cells[i + 2, 3] = (Math.Abs(result["maxValue"]) / 2 + Math.Abs(result["minValue"]) / 2).ToString("0.000");
                            simpleTotalWorksheet.Cells[i + 2, 4] = result["jqml"].ToString("0.000");
                            simpleTotalWorksheet.Cells[i + 2, 5] = result["znb"].ToString("0.000");
                            simpleTotalWorksheet.Cells[i + 2, 6] = (Math.Abs(result["k2_top"]) / 2 + Math.Abs(result["k2_bottom"]) / 2).ToString("0.000");
                            simpleTotalWorksheet.Cells[i + 2, 7] = (Math.Abs(result["zero_1_f"]) / 2 + Math.Abs(result["zero_2_f"]) / 2).ToString("0.000");
                            simpleTotalWorksheet.Cells[i + 2, 8] = (Math.Abs(result["k1_left"]) / 2 + Math.Abs(result["k1_right"]) / 2).ToString("0.000");
                            simpleTotalWorksheet.Cells[i + 2, 9] = result["shyz"].ToString("0.000");
                        }
                    }

                    //保存excel文件
                    workbook.SaveAs(loneExcelTarget);
                    //关闭文件
                    workbook.Close(false, missing, missing);

                    textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "结果写入成功\r\n");
                }
                else
                {
                    totalWorksheet.Cells[i * 5 + 2, 1] = fileName;
                    totalWorksheet.Cells[i * 5 + 2, 2] = "第一零点";
                    totalWorksheet.Cells[i * 5 + 3, 2] = "最高点";
                    totalWorksheet.Cells[i * 5 + 4, 2] = "第二零点";
                    totalWorksheet.Cells[i * 5 + 5, 2] = "最低点";

                    textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "结果有误，写入失败\r\n");
                }

                lineChart(0, loneImageTarget);
                if (File.Exists(loneImageTarget))
                {
                    File.Copy(loneImageTarget, totalImageTarget, true);
                }
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "图形保存成功\r\n");

            }

            //保存excel文件
            totalWorkbook.SaveAs(totalExcelTarget);
            //关闭文件
            totalWorkbook.Close(false, missing, missing);
            excel.Quit();
            excel = null;

        }


        #endregion

        #region 绘制图形

        //绘制图形
        public void lineChart(int period, string fileTarget = null)
        {
            if (period < 0) period = 0;
            ////////////////////ChartArea1属性设置///////////////////////////
            //设置坐标轴名称
            chart1.ChartAreas["ChartArea1"].AxisX.Title = "位移(mm)";
            chart1.ChartAreas["ChartArea1"].AxisY.Title = "力(KN)";

            //设置X轴的标签格式
            chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Format = "0";

            // 局部放大功能
            //chart1.ChartAreas["ChartArea1"].CursorX.IsUserEnabled = true;
            //chart1.ChartAreas["ChartArea1"].CursorY.IsUserEnabled = true;
            //chart1.ChartAreas["ChartArea1"].CursorX.IsUserSelectionEnabled = true;
            //chart1.ChartAreas["ChartArea1"].AxisX.ScaleView.ZoomReset();
            //chart1.ChartAreas["ChartArea1"].AxisX.ScaleView.Zoomable = true;
            //chart1.ChartAreas["ChartArea1"].AxisX.ScrollBar.IsPositionedInside = true;
            //////////////////////Series属性设置///////////////////////////
            //清除所有点
            foreach (Series se in chart1.Series)
            {
                se.Points.Clear();
            }
            //设置显示类型-线型
            chart1.Series[0].ChartType = SeriesChartType.FastLine;
            //是否显示标签的数值
            chart1.Series[0].IsValueShownAsLabel = false;
            //设置图案颜色
            chart1.Series[0].Color = Color.Blue;
            if (fileTarget != null)
            {
                chart1.Series[0].Color = Color.Black;
            }
            //设置图案的宽度
            chart1.Series[0].BorderWidth = 2;
            //设置图案的tooltip
            chart1.Series[0].ToolTip = "位移：#VALX(mm)\r\n力：#VAL(KN)";

            //确定起终点
            int start;
            int end;
            if (period == 0)
            {
                start = 0;
                end = arr1.Count;
            }
            else
            {
                start = zeroArr[(period - 1) * 2];
                end = zeroArr[period * 2];
            }

            //根据选项确定画什么类型的图
            int typeIndex = comboBox3.SelectedIndex;
            if (fileTarget != null)
            {
                for (int i = start; i < end; i++)
                {
                    chart1.Series[0].Points.AddXY(arr1[i], arr2[i]);
                }
            }
            else
            {
                if (typeIndex == 0)
                {
                    for (int i = start; i < end; i++)
                    {
                        chart1.Series[0].Points.AddXY(arr1[i], arr2[i]);
                    }
                }
                else if (typeIndex == 1)
                {
                    //设置坐标轴名称
                    chart1.ChartAreas["ChartArea1"].AxisX.Title = "时间(s)";
                    chart1.ChartAreas["ChartArea1"].AxisY.Title = "位移(mm)";
                    //设置图案的tooltip
                    chart1.Series[0].ToolTip = "时间：#VALX(s)\r\n位移：#VAL(mm)";
                    for (int i = start; i < end; i++)
                    {
                        chart1.Series[0].Points.AddXY(arr0[i], arr1[i]);
                    }
                }
                else
                {
                    //设置坐标轴名称
                    chart1.ChartAreas["ChartArea1"].AxisX.Title = "时间(s)";
                    chart1.ChartAreas["ChartArea1"].AxisY.Title = "力(KN)";
                    //设置图案的tooltip
                    chart1.Series[0].ToolTip = "时间：#VALX(s)\r\n力：#VAL(KN)";
                    for (int i = start; i < end; i++)
                    {
                        chart1.Series[0].Points.AddXY(arr0[i], arr2[i]);
                    }
                }
            }

            //如果是单个周期的其他图将X轴的格式改变一下
            if (period != 0 && typeIndex != 0)
            {
                chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Format = "0.00";
            }

            //初始化做标范围
            if (fileTarget != null)
                initChartMaxAndMinValue(period, true);
            else
                initChartMaxAndMinValue(period);

            if (period > 0 && typeIndex == 0)
            {
                //将几个关键点给显示出来
                this.drawPoints(period);

                //绘制K1的两条直线
                this.drawK1(period);

                //绘制K2的两条直线
                this.drawK2(period);

            }

            //如果有文件路径，保存之
            if (fileTarget != null)
            {
                chart1.SaveImage(fileTarget, ChartImageFormat.Png);
            }
            else
            {
                string fileName = comboBox2.SelectedItem.ToString();
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "第" + period + "周期滞回曲线绘制成功\r\n");
            }

        }

        private void 多图绘制ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //清除所有点
            foreach (Series se in chart1.Series)
            {
                se.Points.Clear();
            }

            int nowIndex = comboBox2.SelectedIndex;
            comboBox2.SelectedIndexChanged -= new EventHandler(comboBox2_SelectedIndexChanged);

            double xmax = 0;
            double ymax = 0;

            for (int i = 0; i < comboBox2.Items.Count; i++)
            {
                comboBox2.SelectedIndex = i;
                string filePath = comboBox2.SelectedValue.ToString();
                if (File.Exists(filePath))
                {
                    // 读取数据
                    arr0.Clear();
                    arr1.Clear();
                    arr2.Clear();
                    readFromFile(filePath);

                    // 添加图层
                    string newSeriesName = "Series" + (i + 7);
                    Series newSeries = chart1.Series.FindByName(newSeriesName);
                    if (newSeries == null) 
                    {
                        chart1.Series.Add(newSeriesName);
                        newSeries = chart1.Series[newSeriesName];
                    }
                    //设置显示类型-线型
                    newSeries.ChartType = SeriesChartType.FastLine;
                    //是否显示标签的数值
                    newSeries.IsValueShownAsLabel = false;
                    //设置图案颜色
                    Random r = new Random();
                    Color color = Color.FromArgb(r.Next(0, 255), r.Next(0, 255), r.Next(0, 255));
                    newSeries.Color = color;
                    //设置图案的宽度
                    newSeries.BorderWidth = 2;
                    //设置图案的tooltip
                    newSeries.ToolTip = "位移：#VALX(mm)\r\n力：#VAL(KN)";
                    
                    for (int j = 0; j < arr1.Count; j++)
                    {
                        if (Math.Abs(arr1[j]) > xmax)
                            xmax = Math.Abs(arr1[j]);
                        if (Math.Abs(arr2[j]) > ymax)
                            ymax = Math.Abs(arr2[j]);
                        newSeries.Points.AddXY(arr1[j], arr2[j]);
                    }
                }
            }
            // 设置xy轴的范围
            double xAxis = getAxisMax(xmax);
            chart1.ChartAreas["ChartArea1"].AxisX.Maximum = xAxis;
            chart1.ChartAreas["ChartArea1"].AxisX.Minimum = -xAxis;
            chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.Interval = xAxis / 5.0;
            double yAxis = getAxisMax(ymax);
            chart1.ChartAreas["ChartArea1"].AxisY.Maximum = yAxis;
            chart1.ChartAreas["ChartArea1"].AxisY.Minimum = -yAxis;
            chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.Interval = yAxis / 5.0;

            comboBox2.SelectedIndex = nowIndex;
            comboBox2.SelectedIndexChanged += new EventHandler(comboBox2_SelectedIndexChanged);
        }
        private void 图片另存ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // 保存图形
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "选择保存位置";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string foldPath = dialog.SelectedPath;
                chart1.SaveImage(foldPath + @"\image.png", ChartImageFormat.Png);
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  图片保存成功\r\n");
            }
        }
        //根据一个值，处理一下，得到轴的边界
        public double getAxisMax(double max)
        { 
            int re = (int)Math.Round(1.2 * max / 10) * 10;
            if (re <= 10) re = (int)Math.Ceiling(1.2 * re);
            return re;
        }

        //绘制K1线
        public void drawK1(int period)
        {
            chart1.Series[4].Points.Clear();
            chart1.Series[5].Points.Clear();

            double left_x1, left_y1, left_x2, left_y2, right_x1, right_y1, right_x2, right_y2;
            this.getK1PointsByPeriod(
                period,
                out left_x1,
                out left_y1,
                out left_x2,
                out left_y2,
                out right_x1,
                out right_y1,
                out right_x2,
                out right_y2
            );

            double k1_left = (left_y2 - left_y1) / (left_x2 - left_x1);
            double k1_right = (right_y2 - right_y1) / (right_x2 - right_x1);
            label41.Text = k1_left.ToString("0.00");
            label42.Text = k1_right.ToString("0.00");

            this.filterK1Points(ref left_x1, ref left_y1, ref left_x2, ref left_y2);
            chart1.Series[4].Points.AddXY(left_x1, left_y1);
            chart1.Series[4].Points.AddXY(left_x2, left_y2);

            this.filterK1Points(ref right_x1, ref right_y1, ref right_x2, ref right_y2);
            chart1.Series[5].Points.AddXY(right_x1, right_y1);
            chart1.Series[5].Points.AddXY(right_x2, right_y2);
        }

        //绘制K2线
        public void drawK2(int period)
        {
            chart1.Series[2].Points.Clear();
            chart1.Series[3].Points.Clear();

            double top_left_x, top_left_y, top_right_x, top_right_y, bottom_left_x, bottom_left_y, bottom_right_x, bottom_right_y;
            this.getK2PointsByPeriod(
                period,
                out top_left_x,
                out top_left_y,
                out top_right_x,
                out top_right_y,
                out bottom_left_x,
                out bottom_left_y,
                out bottom_right_x,
                out bottom_right_y
            );

            double k2_top = (top_right_y - top_left_y) / (top_right_x - top_left_x);
            double k2_bottom = (bottom_right_y - bottom_left_y) / (bottom_right_x - bottom_left_x);
            label43.Text = k2_top.ToString("0.00");
            label44.Text = k2_bottom.ToString("0.00");

            this.filterK2Points(ref top_left_x, ref top_left_y, ref top_right_x, ref top_right_y);
            chart1.Series[2].Points.AddXY(top_left_x, top_left_y);
            chart1.Series[2].Points.AddXY(top_right_x, top_right_y);

            this.filterK2Points(ref bottom_left_x, ref bottom_left_y, ref bottom_right_x, ref bottom_right_y);
            chart1.Series[3].Points.AddXY(bottom_left_x, bottom_left_y);
            chart1.Series[3].Points.AddXY(bottom_right_x, bottom_right_y);
        }

        //绘制几个关键点
        public void drawPoints(int period)
        {
            chart1.Series[1].Points.AddXY(arr1[topArr[period - 1]], arr2[topArr[period - 1]]);
            chart1.Series[1].Points.AddXY(arr1[bottomArr[period - 1]], arr2[bottomArr[period - 1]]);
            chart1.Series[1].Points.AddXY(arr1[zeroArr[(period - 1) * 2]], arr2[zeroArr[(period - 1) * 2]]);
            chart1.Series[1].Points.AddXY(arr1[zeroArr[(period - 1) * 2 + 1]], arr2[zeroArr[(period - 1) * 2 + 1]]);
        }

        //初始化图标的最大值和最小值
        public void initChartMaxAndMinValue(int period, bool isSave = false)
        {
            int typeIndex = comboBox3.SelectedIndex;
            if (isSave == true)
            {
                typeIndex = 0;
                period = 0;
            }
            if (typeIndex < 0) typeIndex = 0;
            if (period < 0) period = 0;
            if (typeIndex == 0)
            {
                //设置X轴
                int x = Math.Abs((int)arr1.Min()) > Math.Abs((int)arr1.Max()) ? Math.Abs((int)arr1.Min()) : Math.Abs((int)arr1.Max());
                int ax = (int)Math.Round(1.2 * x / 10) * 10;
                if (ax <= 10) ax = (int)Math.Ceiling(1.2 * x);
                axis_x_min = -ax;
                axis_x_max = ax;
                chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.Interval = ax / 5.0;

                //设置Y轴
                int y = Math.Abs((int)arr2.Min()) > Math.Abs((int)arr2.Max()) ? Math.Abs((int)arr2.Min()) : Math.Abs((int)arr2.Max());
                int ay = (int)Math.Round(1.2 * y / 10) * 10;
                if (ay <= 10) ay = (int)Math.Ceiling(1.2 * y);
                axis_y_min = -ay;
                axis_y_max = ay;
                chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.Interval = ay / 5;
            }
            else
            {
                if (period == 0)
                {
                    //设置X轴
                    axis_x_min = arr0.Min();
                    axis_x_max = arr0.Max();
                    chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.Interval = (arr0.Max() - arr0.Min()) / 10;
                }
                else
                {
                    axis_x_min = arr0[zeroArr[(period - 1) * 2]];
                    axis_x_max = arr0[zeroArr[period * 2]];
                    chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.Interval = (arr0[zeroArr[period * 2]] - arr0[zeroArr[(period - 1) * 2]]) / 10;
                }
            }

            if (typeIndex == 1)
            {
                //设置Y轴
                int y = Math.Abs((int)arr1.Min()) > Math.Abs((int)arr1.Max()) ? Math.Abs((int)arr1.Min()) : Math.Abs((int)arr1.Max());
                int ay = (int)Math.Round(1.2 * y / 10) * 10;
                if (ay <= 10) ay = (int)Math.Ceiling(1.2 * y);
                axis_y_min = -ay;
                axis_y_max = ay;
                chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.Interval = ay / 5;

            }

            if (typeIndex == 2)
            {
                //设置Y轴
                int y = Math.Abs((int)arr2.Min()) > Math.Abs((int)arr2.Max()) ? Math.Abs((int)arr2.Min()) : Math.Abs((int)arr2.Max());
                int ay = (int)Math.Round(1.2 * y / 10) * 10;
                if (ay <= 10) ay = (int)Math.Ceiling(1.2 * y);
                axis_y_min = -ay;
                axis_y_max = ay;
                chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.Interval = ay / 5;
            }

            setAxis();
        }

        //为图形设置轴线范围
        public void setAxis()
        {
            chart1.ChartAreas["ChartArea1"].AxisX.Minimum = axis_x_min;
            chart1.ChartAreas["ChartArea1"].AxisX.Maximum = axis_x_max;
            chart1.ChartAreas["ChartArea1"].AxisY.Minimum = axis_y_min;
            chart1.ChartAreas["ChartArea1"].AxisY.Maximum = axis_y_max;
        }

        #endregion

        #region 属性的初始化和重置

        //初始化属性
        private void setAttribute()
        {
            this.startRow = 10;
            this.timeCol = 1;
            this.sCol = 2;
            this.fCol = 3;
            this.leftBar = 5;
            this.rightBar = 5;
            this.sRatio = 1.00;
            this.fRatio = 1.00;
            this.dePeriod = 3;
        }

        //属性重置
        public void resetAttribute()
        {
            arr0.Clear();
            arr1.Clear();
            arr2.Clear();
            topArr.Clear();
            bottomArr.Clear();
            zeroArr.Clear();
            comboBox1.Items.Clear();
        }

        #endregion

        #region 其他函数

        //获取默认的周期：默认情况下是3
        public int getDefaultPeriod()
        {
            int pCount = this.getPeriodNum();
            int period = pCount >= this.dePeriod ? this.dePeriod : pCount;
            return period;
        }

        //获取周期数
        public int getPeriodNum()
        {
            int pCount = topArr.Count() >= bottomArr.Count() ? bottomArr.Count() : topArr.Count();
            return pCount;
        }

        //给该显示的内容赋值
        public void setLableText(int period)
        {
            Dictionary<string, double> result = getResult(period);
            label3.Text = result["zero_1_s"].ToString();
            label5.Text = result["zero_1_f"].ToString();
            label8.Text = result["top_s"].ToString();
            label9.Text = result["top_f"].ToString();
            label14.Text = result["zero_2_s"].ToString();
            label16.Text = result["zero_2_f"].ToString();
            label12.Text = result["bottom_s"].ToString();
            label13.Text = result["bottom_f"].ToString();
            label31.Text = result["maxValue"].ToString();
            label33.Text = result["minValue"].ToString();

            label19.Text = result["shyz"].ToString("0.00");
            label21.Text = result["znb"].ToString("0.00") + "(" + result["znb2"].ToString("0.00") + ")";
            label29.Text = result["jqml"].ToString("0.00");

            label41.Text = result["k1_left"].ToString("0.00");
            label42.Text = result["k1_right"].ToString("0.00");
            label43.Text = result["k2_top"].ToString("0.00");
            label44.Text = result["k2_bottom"].ToString("0.00");

            numericUpDown1.ValueChanged -= new EventHandler(numericUpDown1_ValueChanged);
            numericUpDown2.ValueChanged -= new EventHandler(numericUpDown2_ValueChanged);
            numericUpDown1.Value = k1_threshold;
            numericUpDown2.Value = k2_threshold;
            numericUpDown1.ValueChanged += new EventHandler(numericUpDown1_ValueChanged);
            numericUpDown2.ValueChanged += new EventHandler(numericUpDown2_ValueChanged);
        }

        //判断所得的数据是否正确
        public bool dataIsAvailable()
        {
            int pCount = this.getPeriodNum();
            if (pCount <= (zeroArr.Count() - 1) / 2)
            {
                return true;
            }
            return false;
        }

        #endregion

        #region 事件相应

        //点击后选择文件：可以多选
        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Title = "请选择要处理的文件";
            fileDialog.Filter = "支持文件(*.txt,*.xls,*.xlsx)|*.txt;*.xls;*.xlsx";
            fileDialog.RestoreDirectory = false;
            fileDialog.Multiselect = true;
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                comboBox2.SelectedIndexChanged -= new EventHandler(comboBox2_SelectedIndexChanged);
                comboBox2.DataSource = null;
                string[] files = fileDialog.FileNames;
                //putDataToText(files);
                putDataToExcel(files);
                dealFilePath(files);
            }

        }

        //改变周期后显示相应周期的图形
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            int period = comboBox1.SelectedIndex;
            lineChart(period);
            if (period == 0)
            {
                period = getDefaultPeriod();
            }
            setLableText(period);
        }

        //改变文件后显示该文件的信息
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            freshChart();

        }

        //改变图形类型后刷新图表
        private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox2.Items.Count != 0)
            {
                int period = comboBox1.SelectedIndex;
                lineChart(period);
            }
        }

        private void 首选项ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            znq.Control control = new znq.Control(this);
            control.ShowDialog();
        }

        private void 轴线范围ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AxisControl axis = new AxisControl(this);
            axis.Show();
        }

        private void 刚度调整ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ThresholdControl tc = new ThresholdControl(this);
            tc.Show();
        }

        

        private void button3_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            freshChart();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            string filePath = comboBox2.SelectedValue.ToString();
            string fileName = @Path.GetFileNameWithoutExtension(filePath);
            string totalExcelTarget = @Path.GetDirectoryName(filePath) + @"\结果\综合结果\选定周期综合结果.xls";

            if (dataIsAvailable())
            {
                Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
                object missing = System.Reflection.Missing.Value;
                excel.Visible = false;
                excel.UserControl = true;
                Microsoft.Office.Interop.Excel.Workbook totalWorkbook = excel.Workbooks.Open(totalExcelTarget, missing, false, missing, missing, missing, missing, missing, missing, true, missing, missing, missing, missing, missing);
                Microsoft.Office.Interop.Excel.Worksheet simpleTotalWorksheet = totalWorkbook.Worksheets[1];
                Microsoft.Office.Interop.Excel.Worksheet totalWorksheet = totalWorkbook.Worksheets[2];

                int fileIndex = comboBox2.SelectedIndex;
                int period = comboBox1.SelectedIndex;
                if(period == 0)
                {
                    period = this.getDefaultPeriod();
                }
                Dictionary<string, double> result = getResult(period);

                totalWorksheet.Cells[fileIndex * 5 + 2, 1] = fileName;
                totalWorksheet.Cells[fileIndex * 5 + 2, 2] = "第一零点";
                totalWorksheet.Cells[fileIndex * 5 + 2, 3] = result["zero_1_s"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 4] = result["zero_1_f"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 5] = result["maxValue"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 6] = result["minValue"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 7] = result["shyz"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 8] = result["znb"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 9] = result["jqml"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 10] = result["k1_left"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 11] = result["k1_right"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 12] = result["k2_top"];
                totalWorksheet.Cells[fileIndex * 5 + 2, 13] = result["k2_bottom"];
                totalWorksheet.Cells[fileIndex * 5 + 3, 2] = "最高点";
                totalWorksheet.Cells[fileIndex * 5 + 3, 3] = result["top_s"];
                totalWorksheet.Cells[fileIndex * 5 + 3, 4] = result["top_f"];
                totalWorksheet.Cells[fileIndex * 5 + 4, 2] = "第二零点";
                totalWorksheet.Cells[fileIndex * 5 + 4, 3] = result["zero_2_s"];
                totalWorksheet.Cells[fileIndex * 5 + 4, 4] = result["zero_2_f"];
                totalWorksheet.Cells[fileIndex * 5 + 5, 2] = "最低点";
                totalWorksheet.Cells[fileIndex * 5 + 5, 3] = result["bottom_s"];
                totalWorksheet.Cells[fileIndex * 5 + 5, 4] = result["bottom_f"];


                simpleTotalWorksheet.Cells[fileIndex + 2, 1] = fileName;
                simpleTotalWorksheet.Cells[fileIndex + 2, 2] = (Math.Abs(result["top_s"]) / 2 + Math.Abs(result["bottom_s"]) / 2).ToString("0.0");
                simpleTotalWorksheet.Cells[fileIndex + 2, 3] = (Math.Abs(result["maxValue"]) / 2 + Math.Abs(result["minValue"]) / 2).ToString("0.000");
                simpleTotalWorksheet.Cells[fileIndex + 2, 4] = result["jqml"].ToString("0.000");
                simpleTotalWorksheet.Cells[fileIndex + 2, 5] = result["znb"].ToString("0.000");
                simpleTotalWorksheet.Cells[fileIndex + 2, 6] = (Math.Abs(result["k2_top"]) / 2 + Math.Abs(result["k2_bottom"]) / 2).ToString("0.000");
                simpleTotalWorksheet.Cells[fileIndex + 2, 7] = (Math.Abs(result["zero_1_f"]) / 2 + Math.Abs(result["zero_2_f"]) / 2).ToString("0.000");
                simpleTotalWorksheet.Cells[fileIndex + 2, 8] = (Math.Abs(result["k1_left"]) / 2 + Math.Abs(result["k1_right"]) / 2).ToString("0.000");
                simpleTotalWorksheet.Cells[fileIndex + 2, 9] = result["shyz"].ToString("0.000");

                //保存excel文件
                totalWorkbook.Save();
                //关闭文件
                totalWorkbook.Close(false, missing, missing);
                excel.Quit();
                excel = null;

                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "结果写入成功\r\n");
            }
            else
            {
                textBox3.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  文件" + fileName + "结果有误，写入失败\r\n");
            }
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            k1_threshold = int.Parse(numericUpDown1.Value.ToString());
            int period = comboBox1.SelectedIndex;
            if (period != 0)
                drawK1(period);
        }

        private void numericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            k2_threshold = int.Parse(numericUpDown2.Value.ToString());
            int period = comboBox1.SelectedIndex;
            if (period != 0)
                drawK2(period);
        }

        #endregion



    }
}
